package com.tgy.MyFlowable.workflow.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ctsi.core.common.api.Result;
import com.ctsi.core.common.entity.LoginUser;
import com.ctsi.core.common.util.$;
import com.ctsi.core.common.util.SecurityUtil;
import com.ctsi.core.common.util.StringPool;
import com.ctsi.core.database.util.PageUtil;
import com.ctsi.core.workflow.enums.DelegateStatusEnum;
import com.ctsi.system.service.IRoleService;
import com.ctsi.system.service.IUserService;
import com.ctsi.workflow.dto.FlwTodoTaskDTO;
import com.ctsi.workflow.factory.FlowableAssigneeFactory;
import com.ctsi.workflow.service.IFlwInstanceService;
import com.ctsi.workflow.service.IFlwTodoTaskService;
import com.ctsi.workflow.vo.FlwInstanceVO;
import com.ctsi.workflow.vo.FlwTodoTaskVO;
import lombok.RequiredArgsConstructor;
import org.flowable.engine.TaskService;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 待办任务业务实现类
 *
 * @version 1.0
 * @author: wang xiao xiang
 * @date: 2021/8/8 19:52
 */
@Service
@RequiredArgsConstructor
public class FlwTodoTaskServiceImpl implements IFlwTodoTaskService {
    private final TaskService taskService;
    private final IFlwInstanceService flwInstanceService;
    private final static String ID = "id";

    @Autowired
    private IUserService userService;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private IRoleService roleService;

    @Override
    public IPage<FlwTodoTaskVO> page(FlwTodoTaskDTO flwTodoTaskDTO) {
        TaskQuery taskQuery = taskService.createTaskQuery();
        LoginUser loginUser = SecurityUtil.getUsername(request);
        Long userId = loginUser.getId();
        // 角色信息
        List<Dict> roles = roleService.getLoginRoles(userId);
        //Long userId = MarsContextHolder.getUserId();
        //LoginUser loginUser = userService.getLoginUserByRequest(userId, request);
        List<String> loginUserRoleIds = null;
        if (CollectionUtil.isNotEmpty(roles)) {
            loginUserRoleIds = roles.stream().map(dict -> dict.getStr(ID)).collect(Collectors.toList());
        }
        //查询激活的
        taskQuery.active();
        //候选人或办理人
        taskQuery.taskCandidateOrAssigned($.toStr(userId));
        //候选组（角色），此处判空是为了防止用户无角色时报错（如超级管理员角色是不存在的），一般不会存在此问题
        if ($.isNotEmpty(loginUserRoleIds)) {
            taskQuery.taskCandidateGroupIn(loginUserRoleIds);
        }
        if ($.isNotNull(flwTodoTaskDTO)) {
            //流程名称模糊查询
            if ($.isNotEmpty(flwTodoTaskDTO.getProcessName())) {
                taskQuery.processDefinitionNameLike(StringPool.PERCENT + flwTodoTaskDTO.getProcessName() + StringPool.PERCENT);
            }
            //任务名称模糊查询
            if ($.isNotEmpty(flwTodoTaskDTO.getName())) {
                taskQuery.taskNameLike(StringPool.PERCENT + flwTodoTaskDTO.getName() + StringPool.PERCENT);
            }
            //流程分类查询
            if ($.isNotEmpty(flwTodoTaskDTO.getCategory())) {
                taskQuery.processCategoryIn(CollectionUtil.newHashSet(flwTodoTaskDTO.getCategory()));
            }
            //创建时间范围查询
            if (ObjectUtil.isAllNotEmpty(flwTodoTaskDTO.getStartDate(), flwTodoTaskDTO.getEndDate())) {
                taskQuery.taskCreatedAfter(DateUtil.parseDateTime(flwTodoTaskDTO.getStartDate()))
                        .taskCreatedBefore(DateUtil.parseDateTime(flwTodoTaskDTO.getEndDate()));
            }
            //优先级查询
            if (ObjectUtil.isNotEmpty(flwTodoTaskDTO.getPriority())) {
                taskQuery.taskPriority(flwTodoTaskDTO.getPriority());
            }
        }
        //根据任务创建时间倒序，最新任务在最上面
        taskQuery.orderByTaskCreateTime().desc();
        Page<FlwTodoTaskVO> defaultPage = PageUtil.getPage(flwTodoTaskDTO);
        long current = defaultPage.getCurrent();
        long size = defaultPage.getSize();
        List<Task> taskList = taskQuery
                .listPage(Convert.toInt((current - 1) * size), Convert.toInt(size));
        defaultPage.setTotal(taskQuery.count());
        List<FlwTodoTaskVO> collect = taskList.stream().map(task -> convertToTodoTaskVO(task)).collect(Collectors.toList());
        defaultPage.setRecords(collect);
        return defaultPage;
    }

    private FlwTodoTaskVO convertToTodoTaskVO(Task task){
        FlwTodoTaskVO flwTodoTaskVO = $.copy(task, FlwTodoTaskVO.class);
        flwTodoTaskVO.setActivityId(task.getTaskDefinitionKey());
        //委托中：已经委托了，对方还没给出意见(没做任何处理); 委托结束：该任务已经解决(resolved)，即已经给出意见，但是还没完成该任务
        //当被委托人解决任务时，该任务又回到自己名下，由自己完成后进入下一节点
        //如果委托状态为空，则表示未委托，否则表示委托了
        if ($.isEmpty(task.getDelegationState())) {
            //非委托任务
            flwTodoTaskVO.setDelegationState(DelegateStatusEnum.NOT.getCode());
        } else {
            //获取委托状态
            DelegationState delegationState = task.getDelegationState();
            //委托中
            if (DelegationState.PENDING.equals(delegationState)) {
                flwTodoTaskVO.setDelegationState(DelegateStatusEnum.PENDING.getCode());
            }
            //委托结束
            if (DelegationState.RESOLVED.equals(delegationState)) {
                flwTodoTaskVO.setDelegationState(DelegateStatusEnum.RESOLVED.getCode());
            }
        }
        //任务所属人不为空
        if ($.isNotEmpty(task.getOwner())) {
            //任务所属人
            flwTodoTaskVO.setOwner(task.getOwner());
            //任务所属人名称
            flwTodoTaskVO.setOwnerName(FlowableAssigneeFactory.getAssigneeNameByUserId(task.getOwner()));
        }
        //若任务办理人不为空，即指定了具体的人，则设置该办理人名字
        if ($.isNotBlank(task.getAssignee())) {
            //获取任务办理人
            flwTodoTaskVO.setAssigneeName(Result.data(userService.getById($.toLong(task.getAssignee()))).getData().getAccount());
            flwTodoTaskVO.setAssigneeInfo("处理人:" + flwTodoTaskVO.getAssigneeName());
        } else {
            //任务办理人为空，即没有指定具体的人，则可能是候选人或候选组，则设置候选人或候选组名字
//            flwTodoTaskVO.setAssigneeName(Result.data(userService.getById($.toLong(task.getId()))).getData().getAccount());
            flwTodoTaskVO.setAssigneeInfo("处理人:" + flwTodoTaskVO.getAssigneeName() == null ? "" : flwTodoTaskVO.getAssigneeName());
        }
        flwTodoTaskVO.setFormatCreateTime($.formatPastTime(task.getCreateTime()));
        //流程实例信息
        FlwInstanceVO procIns = flwInstanceService.detail(task.getProcessInstanceId());
        flwTodoTaskVO.setProcIns(procIns);
        return flwTodoTaskVO;
    }
}
